package demo1

import (
	"fmt"
	"unsafe"
)

// TestDemo12 常量
func TestDemo12() {
	// 1. 变量声明
	const a int = 1

	// 2. 多个相同类型的声明
	const b1, b2 int = 11, 22

	// 3. 常量的使用、计算
	const LENGTH int = 10
	const WIDTH int = 20
	var area int
	const c1, c12, c13 = 5, false, "string"

	area = LENGTH * WIDTH

	fmt.Printf("面积是：%d", area)
	println()
	println(c1, c12, c13)

	// 4. 常量使用于枚举
	const (
		Unknow = 0
		Female = 1
		Male   = 2
	)

	// 5. 常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中，函数必须是内置函数，否则编译不过：
	const (
		d1 = "abc"
		d2 = len(d1)
		d3 = unsafe.Sizeof(d1)
	)
	println(d1, d2, d3)

	/*
		6. iota
			1. iota，特殊常量，可以认为是一个可以被编译器修改的常量。
			2. ota 在 const关键字出现时将被重置为 0(const 内部的第一行之前)，const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
			3. iota 可以被用作枚举值：
	*/
	const (
		e1 = iota
		e2 = iota
		e3 = iota
	)
	println(e1, e2, e3)

	// 上面形式的简写
	const (
		f1 = iota
		f2
		f3
	)
	println(f1, f2, f3)

	// 默认值1
	const (
		g1 = 10
		g2 // 默认赋值给 10
		g3 // 默认赋值给 10
	)
	fmt.Println(g1, g2, g3)

	// 默认值2
	const (
		h1 = 15
		h2 // 默认赋值给 15
		h3 // 默认赋值给 15
		h4 = "test"
		h5 // 默认赋值给 test
		h6 // 默认赋值给 test
	)
	println(h1, h2, h3, h4, h5, h6)

	// 默认值和 iota
	const (
		i1 = iota
		i2         // iota += 1
		i3 = "hao" // //独立值，iota += 1
		i4         // 默认值 hao, iota += 1
		i5 = 20    // 20, iota += 1
		i6         // 默认值 20, iota += 1
		i7 = iota  // iota 恢复赋值
		i8         // iota += 1
	)
	println(i1, i2, i3, i4, i5, i6, i7, i8)

	// iota 进行位的计算
	const (
		j1 = 1 << iota // 01: 1
		j2             // 010: 2
		j3             // 0100: 4
		j4 = 3 << iota // 0100000: 10
		j5
		j6
	)
	fmt.Println(j1, j2, j3, j4, j5, j6)
}
